package sy4_Creational_Pattern.builder.wuwan;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * construct：建造、建设，不及物动词，较宽泛
 * build：建造、构建，及物动词，较具体
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
class Product{   //复杂产品角色
    private String food;  //食品---作为产品部件之一
    private String drink;  //饮料---作为产品部件之二
}

abstract class Builder{   //抽象建造者
    //定义复杂产品部件建造的抽象方法
    public abstract String buildFood();  //建造食品
    public abstract String buildDrink();  //建造饮料
}

class ConcreteBuilderA extends Builder{  //麦当劳快餐
    public ConcreteBuilderA() {
        System.out.println("麦当劳快餐");
    }

    @Override
    public String buildFood() {
        return "汉堡";
    }
    @Override
    public String buildDrink() {
        return "雪碧";
    }

    public Product getProduct(){   //普通方法，供产品指挥者调用
        Product product = new Product();
        product.setFood(buildFood());
        product.setDrink(buildDrink());
        return product;
    }
}

class ConcreteBuilderB extends Builder{  //肯德鸡快餐
    public ConcreteBuilderB() {
        System.out.println("肯德鸡快餐");
    }
    @Override
    public String buildFood() {
        return "炸鸡";
    }
    @Override
    public String buildDrink() {
        return "可乐";
    }

    public Product getProduct(){   //普通方法，供产品指挥者调用
        Product product = new Product();
        product.setFood(buildFood());
        product.setDrink(buildDrink());
        return product;
    }
}

class Director{   //指挥者
    private Builder builder;
    
    public Director(Builder builder) {
        this.builder = builder;
    }

    public void construct(){
        //建造过程控制，可注释部分语句
        builder.buildFood();
        //builder.buildDrink();
    }
}

public class Client {
    public static void main(String[] args) {
        ConcreteBuilderA builderA=new ConcreteBuilderA();
        Director director = new Director(builderA);
        director.construct();  //控制产品构建
        Product product = builderA.getProduct();
        System.out.println(product);

        //相同的建造过程，可以有不同的产品表示
        ConcreteBuilderB builderB=new ConcreteBuilderB();
        /*director=new Director(builderB);
        director.construct();*/
        product=builderB.getProduct();
        System.out.println(product);
    }
}
